package io.gitee.kotle.player.download

import android.content.Context
import androidx.annotation.WorkerThread
import androidx.media3.common.MediaItem
import io.gitee.kotle.player.download.impl.exoplayer.ExoPlayerDownloadImpl
import kotlinx.coroutines.CoroutineScope

/**
 *
 * 描述：默认不会执行下载，必须先手动调用[resumeDownloads]来开始下载流程
 *
 * @author Jiale.Wei
 *
 * 创建时间：2023/4/26 14:36
 *
 */
interface IPlayerDownload<Media> {
    companion object {
        fun exoPlayerDownload(context: Context): IPlayerDownload<MediaItem> =
            ExoPlayerDownloadImpl(context)
    }

    sealed interface State {
        data object Queued : State
        data object Stopped : State
        data object Downloading : State
        data object Completed : State
        data object Failed : State
        data object Removing : State
        data object Removed : State
        data object Restarting : State
    }

    class DownloadInfo<Media>(
        val mediaId: String,
        val media: Media,/*当前的媒体*/
        val state: State,/*下载状态*/
        val extra: ByteArray?,/*下载的额外信息*/
        val downloadedCount: Long,/*已下载字节*/
        val totalCount: Long,/*总的下载字节*/
        val startTimeMs: Long,/*任务创建时间戳*/
        val updateTimeMs: Long,/*最后更新时间戳*/
    )

    /**
     * 下载监听器
     */
    interface IListener<Media> {
        /**
         * 下载状态回调
         */
        suspend fun onDownload(downloadInfo: DownloadInfo<Media>) {

        }

        /**
         * 下载
         */
        suspend fun onDownloadList(downloadList: List<DownloadInfo<Media>>) {

        }
    }

    /**
     * 协程作用域
     */
    val scope: CoroutineScope

    /**
     * 同时最大的下载数
     */
    var maxParallelDownloads: Int

    /**
     * 开始下载
     */
    fun addDownload(mediaId: String, media: Media, extra: ByteArray?, reason: Int? = null)

    /**
     * 添加监听器
     * 如果[mediaId]为null，则回调所有的资源
     * 否则只回调对应的资源
     */
    fun addListener(listener: Pair<@ParameterName("mediaId") String?, IListener<Media>>?)

    /**
     * 移除监听器
     */
    fun removeListener(listener: Pair<@ParameterName("mediaId") String?, IListener<Media>>?)

    /**
     * 获取下载
     */
    @WorkerThread
    fun getDownload(mediaId: String): DownloadInfo<Media>?

    /**
     * 获取下载
     */
    fun getDownload(mediaId: String, block: Function1<DownloadInfo<Media>?, Unit>)

    /**
     * 根据状态查询下载
     */
    @WorkerThread
    fun getDownloadsByStates(states: List<State>): MutableList<DownloadInfo<Media>>

    /**
     * 根据状态查询下载
     */
    fun getDownloadsByStates(
        states: List<State>,
        block: Function1<MutableList<DownloadInfo<Media>>, Unit>
    )

    /**
     * 获取所有下载
     */
    @WorkerThread
    fun getAllDownloads(): MutableList<DownloadInfo<Media>>

    /**
     * 获取所有下载
     */
    fun getAllDownloads(block: Function1<MutableList<DownloadInfo<Media>>, Unit>)

    /**
     * 获取当前下载（状态不是终态的下载）
     */
    fun getCurrentDownloads(): MutableList<DownloadInfo<Media>>

    /**
     * 获取当前下载（状态不是终态的下载）
     */
    fun getCurrentDownloads(block: Function1<MutableList<DownloadInfo<Media>>, Unit>)

    /**
     * 移除下载
     */
    fun removeDownload(mediaId: String)

    /**
     * 恢复下载
     */
    fun resumeDownload(mediaId: String)

    /**
     * 恢复所有下载
     */
    fun resumeDownloads()

    /**
     * 暂停所有下载
     */
    fun pauseDownloads()

    /**
     * 停止下载
     */
    fun pauseDownload(mediaId: String, reason: Int = -1)

    /**
     * 移除所有下载
     */
    fun removeAllDownloads()

    /**
     * 释放资源
     */
    fun release()
}